package com.szz.cardecision.controller;

import com.szz.cardecision.entity.Consultation;
import com.szz.cardecision.entity.User;
import com.szz.cardecision.mapper.ConsultationMapper;
import com.szz.cardecision.mapper.UserMapper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Controller
@PreAuthorize("hasRole('ADMIN')")
public class AdminController {
    private final UserMapper userMapper;
    private final ConsultationMapper consultationMapper;

    public AdminController(UserMapper userMapper, ConsultationMapper consultationMapper) {
        this.userMapper = userMapper;
        this.consultationMapper = consultationMapper;
    }

    @GetMapping("/admin")
    public String dashboard(Model model) {
        List<User> users = userMapper.findAll();
        List<Consultation> consults = consultationMapper.findAll();

        Map<String, Long> hotBodyTypes = consults.stream()
                .filter(c -> c.getBodyType() != null)
                .collect(Collectors.groupingBy(Consultation::getBodyType, Collectors.counting()));
        Map<String, Long> hotScenes = consults.stream()
                .filter(c -> c.getScenes() != null)
                .collect(Collectors.groupingBy(Consultation::getScenes, Collectors.counting()));
        Map<String, Long> hotFuel = consults.stream()
                .filter(c -> c.getFuelType() != null)
                .collect(Collectors.groupingBy(Consultation::getFuelType, Collectors.counting()));

        Function<Map<String, Long>, List<Map.Entry<String, Long>>> top5 = m -> m.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .limit(5)
                .collect(Collectors.toList());

        model.addAttribute("userCount", users.size());
        model.addAttribute("consultCount", consults.size());
        model.addAttribute("topBodyTypes", top5.apply(hotBodyTypes));
        model.addAttribute("topScenes", top5.apply(hotScenes));
        model.addAttribute("topFuel", top5.apply(hotFuel));
        return "admin_dashboard";
    }

    @GetMapping("/admin/consultations")
    public String consultations(Model model) {
        model.addAttribute("items", consultationMapper.findAll());
        return "admin_consultations";
    }

    @GetMapping("/admin/users")
    public String users(Model model) {
        model.addAttribute("items", userMapper.findAll());
        return "admin_users";
    }

    @PostMapping("/admin/users/{id}/delete")
    public String deleteUser(@PathVariable Long id) {
        userMapper.deleteById(id);
        return "redirect:/admin/users";
    }

    @PostMapping("/admin/users/{id}/grant-admin")
    public String grantAdmin(@PathVariable Long id) {
        User u = userMapper.findById(id).orElse(null);
        if (u != null) {
            u.setAdmin(true);
            userMapper.update(u);
        }
        return "redirect:/admin/users";
    }

    @PostMapping("/admin/users/{id}/revoke-admin")
    public String revokeAdmin(@PathVariable Long id) {
        User u = userMapper.findById(id).orElse(null);
        if (u != null) {
            u.setAdmin(false);
            userMapper.update(u);
        }
        return "redirect:/admin/users";
    }
}